package us.versus.them.stickler;

class Vertlet {
	public var current : Point; // current position
	public var last    : Point; // last position
	public var force   : Point; // force accumulator
	public var tmp     : Point;

	public function new( point : Point ) {
		this.nu( point.x, point.y, point.z );
	}

	public function nu( x : Float, y : Float, z : Float ) {
		current = new Point( x, y, z );
		last    = new Point( x, y, z );
		force   = new Point( 0, 0, 0 );
		tmp     = new Point( 0, 0, 0 );
	}

	public static function gnu( x : Float, y : Float, z : Float, offset : Point, scale : Float ) {
		return new Vertlet(
			Point.scale( Point.addTo( new Point( x, y, z ), offset ), scale )
		);
	}

	public function stop() : Vertlet {
		Point.assignPt( last, current );
		Point.scale( force, 0 );
		return this;
	}

	public function vertlet( timeStep : Float, damping : Float ) : Vertlet {
		Point.assignPt( tmp, current );

		//x += x-oldx+a*fTimeStep*fTimeStep;
		current.x += ( current.x - last.x ) * damping + force.x * timeStep * timeStep;
		current.y += ( current.y - last.y ) * damping + force.y * timeStep * timeStep;
		current.z += ( current.z - last.z ) * damping + force.z * timeStep * timeStep;

		Point.assignPt( last, tmp );

		return this;
	}

	public static function accumulateForces( vertlet : Vertlet, gravity : Point ) {
		Point.assignPt( vertlet.force, gravity );
	}

	public static function addTo( vertlet : Vertlet, point : Point ) : Vertlet {
		Point.addTo( vertlet.current, point );
		return vertlet;
	}

	public static function offset( vertlet : Vertlet, point : Point ) : Vertlet {
		Vertlet.addTo( vertlet, point );
		return vertlet.stop();
	}
}
